;(function (window, undefined) {
    var S = function (selector) {
        return new S.fn.init(selector);
    };
    S.fn = S.prototype = {
        length: 0,
        constructor: S,
        // 实例化化方法，这个方法可以称作 jQuery 对象构造器
        init: function (selector) {
            var nodes = [];
            if (typeof selector === 'undefined') {
                return this;
            }
            if (typeof selector === 'string') {
                nodes = [].slice.call(document.querySelectorAll(selector));
            }
            if (selector.nodeType) {
                nodes[0] = selector;
            }
            for (var i = 0; i < nodes.length; i++) {
                [].push.call(this, nodes[i]);
            }
            return this;
        },
        get: function (num) {

            // Return all the elements in a clean array
            if (num == null) {
                return [].slice.call(this);
            }

            // Return just the one element from the set
            return num < 0 ? this[num + this.length] : this[num];
        },
        slice: function () {
            return this.pushStack([].slice.apply(this, arguments));
        },

        first: function () {
            return this.eq(0);
        },

        last: function () {
            return this.eq(-1);
        },

        eq: function (i) {
            var len = this.length,
                j = +i + ( i < 0 ? len : 0 );
            return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
        },
        pushStack: function (elems) {

            // Build a new jQuery matched element set
            var ret = S.merge(this.constructor(), elems);

            // Add the old object onto the stack (as a reference)
            ret.prevObject = this;

            // Return the newly-formed element set
            return ret;
        },

        end: function () {
            return this.prevObject || this.constructor();
        },

        // For internal use only.
        // Behaves like an Array's method, not like a jQuery method.
        push: [].push,
        sort: [].sort,
        splice: [].splice,
        each: S.each

    };

    function isArrayLike(obj) {

        // Support: real iOS 8.2 only (not reproducible in simulator)
        // `in` check used to prevent JIT error (gh-2145)
        // hasOwn isn't used here due to false negatives
        // regarding Nodelist length in IE
        var length = !!obj && "length" in obj && obj.length,
            type = S.type(obj);

        if (type === "function" || S.isWindow(obj)) {
            return false;
        }

        return type === "array" || length === 0 ||
            typeof length === "number" && length > 0 && ( length - 1 ) in obj;
    }

    S.extend = S.fn.extend = function () {
        var options, name, src, copy, copyIsArray, clone,
            target = arguments[0] || {},
            i = 1,
            length = arguments.length,
            deep = false;

        // Handle a deep copy situation
        if (typeof target === "boolean") {
            deep = target;

            // Skip the boolean and the target
            target = arguments[i] || {};
            i++;
        }

        // Handle case when target is a string or something (possible in deep copy)
        if (typeof target !== "object" && !S.isFunction(target)) {
            target = {};
        }

        // Extend jQuery itself if only one argument is passed
        if (i === length) {
            target = this;
            i--;
        }

        for (; i < length; i++) {

            // Only deal with non-null/undefined values
            if (( options = arguments[i] ) != null) {

                // Extend the base object
                for (name in options) {
                    src = target[name];
                    copy = options[name];

                    // Prevent never-ending loop
                    if (target === copy) {
                        continue;
                    }

                    // Recurse if we're merging plain objects or arrays
                    if (deep && copy && ( S.isPlainObject(copy) ||
                            ( copyIsArray = Array.isArray(copy) ) )) {

                        if (copyIsArray) {
                            copyIsArray = false;
                            clone = src && Array.isArray(src) ? src : [];

                        } else {
                            clone = src && S.isPlainObject(src) ? src : {};
                        }

                        // Never move original objects, clone them
                        target[name] = S.extend(deep, clone, copy);

                        // Don't bring in undefined values
                    } else if (copy !== undefined) {
                        target[name] = copy;
                    }
                }
            }
        }

        // Return the modified object
        return target;
    };
    S.extend({


        // Assume jQuery is ready without the ready module
        isReady: true,

        error: function (msg) {
            throw new Error(msg);
        },

        noop: function () {
        },

        isFunction: function (obj) {
            return S.type(obj) === "function";
        },

        isWindow: function (obj) {
            return obj != null && obj === obj.window;
        },

        isNumeric: function (obj) {

            // As of jQuery 3.0, isNumeric is limited to
            // strings and numbers (primitives or objects)
            // that can be coerced to finite numbers (gh-2662)
            var type = S.type(obj);
            return ( type === "number" || type === "string" ) &&

                // parseFloat NaNs numeric-cast false positives ("")
                // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
                // subtraction forces infinities to NaN
                !isNaN(obj - parseFloat(obj));
        },

        isPlainObject: function (obj) {
            var proto, Ctor;

            // Detect obvious negatives
            // Use toString instead of jQuery.type to catch host objects
            if (!obj || {}.toString.call(obj) !== "[object Object]") {
                return false;
            }

            proto = Object.getPrototypeOf(obj);

            // Objects with no prototype (e.g., `Object.create( null )`) are plain
            if (!proto) {
                return true;
            }

            // Objects with prototype are plain iff they were constructed by a global Object function
            Ctor = {}.hasOwnProperty.call(proto, "constructor") && proto.constructor;
            return typeof Ctor === "function" && {}.hasOwnProperty.toString.call(Ctor) === {}.hasOwnProperty.toString.call(Object);
        },

        isEmptyObject: function (obj) {

            /* eslint-disable no-unused-vars */
            // See https://github.com/eslint/eslint/issues/6125
            var name;

            for (name in obj) {
                return false;
            }
            return true;
        },

        each: function (obj, callback) {
            var length, i = 0;

            if (isArrayLike(obj)) {
                length = obj.length;
                for (; i < length; i++) {
                    if (callback.call(obj[i], i, obj[i]) === false) {
                        break;
                    }
                }
            } else {
                for (i in obj) {
                    if (callback.call(obj[i], i, obj[i]) === false) {
                        break;
                    }
                }
            }

            return obj;
        },
        type: function (obj) {
            if (obj == null) {
                return obj + "";
            }

            // Support: Android <=2.3 only (functionish RegExp)
            return typeof obj === "object" || typeof obj === "function" ?
                {}[{}.toString.call(obj)] || "object" :
                typeof obj;
        },

        // Support: Android <=4.0 only
        trim: function (text) {
            return text == null ?
                "" :
                ( text + "" ).replace(rtrim, "");
        },

        inArray: function (elem, arr, i) {
            return arr == null ? -1 : indexOf.call(arr, elem, i);
        },

        // Support: Android <=4.0 only, PhantomJS 1 only
        // push.apply(_, arraylike) throws on ancient WebKit
        merge: function (first, second) {
            var len = +second.length,
                j = 0,
                i = first.length;

            for (; j < len; j++) {
                first[i++] = second[j];
            }

            first.length = i;

            return first;
        },
        ajax: function (opt) {
            opt = opt || {};
            opt.method = opt.method ? opt.method.toUpperCase() : 'GET';
            opt.url = opt.url || '';
            opt.async = opt.async === false ? false : true;
            opt.dataType = opt.dataType || 'json';
            opt.data = opt.data || null;
            opt.success = opt.success || function () {
            };

            var xmlHttp = null;
            if (XMLHttpRequest) {
                xmlHttp = new XMLHttpRequest();
            }
            else {
                xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
            }
            var params = [];
            for (var key in opt.data) {
                params.push(key + '=' + opt.data[key]);
            }
            var postData = params.join('&');
            if (opt.method.toUpperCase() === 'POST') {
                xmlHttp.open(opt.method, opt.url, opt.async);
                xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
                if (postData)
                    xmlHttp.send(postData);
            }
            else if (opt.method.toUpperCase() === 'GET') {
                xmlHttp.open(opt.method, postData ? opt.url + '&' + postData : opt.url, opt.async);
                xmlHttp.send(null);
            }
            if (opt.async) {
                xmlHttp.onreadystatechange = function () {
                    if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
                        var data = xmlHttp.responseText;
                        if (opt.dataType === 'json') {
                            data = JSON.parse(data);
                        }
                        opt.success(data);
                    }
                };
            } else {
                var data = xmlHttp.responseText;
                if (opt.dataType === 'json') {
                    data = JSON.parse(data);
                }
                opt.success(data);
            }
        }
    });


    S.fn.extend({
        each: function (callback) {
            S.each(this, callback);
        },
        hasClass: function (className, item) {
            return item.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
        },
        addClass: function (className) {
            S.each(this, function (i, item) {
                if (!S(item).hasClass(className, item))
                    item.className += " " + className;
            });
            return this;
        },
        toggleClass: function (className) {
            S.each(this, function (i, item) {
                if (S(item).hasClass(className, item)) {
                    S(item).removeClass(className);
                } else {
                    S(item).addClass(className);
                }
            });
            return this;
        },
        removeClass: function (className) {
            S.each(this, function (i, item) {
                if (S(item).hasClass(className, item)) {
                    var reg = new RegExp('(\\s|^)' + className + '(\\s|$)');
                    item.className = item.className.replace(reg, ' ');
                }
            });
            return this;
        },
        html: function (content) {
            S.each(this, function (i, item) {
                item.innerHTML = content;
            })
        },
        text: function (content) {
            S.each(this, function (i, item) {
                item.innerText = content;
            })
        },
        attr: function (attribute, value) {
            S.each(this, function (i, item) {
                item[attribute] = value;
            })
            return this
        },
        find: function (selector) {
        },
        css:function () {

        },
        hide:function () {
            S.each(this, function (i, item) {
                item.style.display = 'none';
            })
        },
        show:function () {
            S.each(this, function (i, item) {
                item.style.display = 'block';
            })
        },
        /**
         *
         * @param h 元素高度
         * @param w 元素宽度
         * @param t 元素上边距
         * @param l 元素左边距
         * @param r 行数
         * @param c 列数
         */
        position: function (h, w, t, l, r, c) {
            //绝对定位
            //每个元素宽高
            var height = h,
                width = w;
            //每个元素偏移间隔
            var offsetTop = t, offsetLeft = l;
            //总行数，总列数
            var rowNum = r, colNum = c;
            var curRow, curCol;
            for (var i = 0; i < this.length; i++) {
                curRow = Math.floor(i / colNum);
                curCol = i % colNum;
                this[i].style.top = (height + offsetTop) * curRow + 'px';
                this[i].style.left = (width + offsetLeft) * curCol + 'px';
            }
        }
    });
    S.fn.init.prototype = S.fn;
    if (typeof $ === "function") {
        window.S = S;
    } else {
        window.$ = window.S = S;
    }
})(window);